/**
 * Copyright (C) 2014-2019 by Wen Yu.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 * <p>
 * Any modifications to this file must keep this entire header intact.
 * <p>
 * Change History - most recent changes go on top of previous changes
 * <p>
 * VersionInfo.java
 * <p>
 * Adobe IRB version info resource wrapper
 * <p>
 * Who   Date       Description
 * ====  =========  =================================================
 * WY    17Apr2015  Added new constructor
 * WY    17Apr2015  Changed version and fileVersion data type to int
 */

package com.symaster.common.pixy.meta.adobe;

import com.symaster.common.pixy.io.IOUtils;
import com.symaster.common.pixy.string.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.nio.charset.StandardCharsets;

public class VersionInfo extends _8BIM {
    // Obtain a logger instance
    private static final Logger LOGGER = LoggerFactory.getLogger(VersionInfo.class);
    //
    private int version;
    private boolean hasRealMergedData;
    private String writerName;
    private String readerName;
    private int fileVersion;

    public VersionInfo() {
        this("VersionInfo");
    }

    public VersionInfo(String name) {
        super(ImageResourceID.VERSION_INFO, name, null);
    }

    public VersionInfo(String name, byte[] data) {
        super(ImageResourceID.VERSION_INFO, name, data);
        read();
    }

    public VersionInfo(int version, boolean hasRealMergedData, String writerName, String readerName, int fileVersion) {
        this("VersionInfo", version, hasRealMergedData, writerName, readerName, fileVersion);
    }

    public VersionInfo(String name, int version, boolean hasRealMergedData, String writerName, String readerName, int fileVersion) {
        super(ImageResourceID.VERSION_INFO, name, null);
        this.version = version;
        this.hasRealMergedData = hasRealMergedData;
        this.writerName = writerName;
        this.readerName = readerName;
        this.fileVersion = fileVersion;
    }

    public int getFileVersion() {
        return fileVersion;
    }

    public void setFileVersion(int fileVersion) {
        if (fileVersion < 0)
            throw new IllegalArgumentException("File version number is negative");
        this.fileVersion = fileVersion;
    }

    public int getVersion() {
        return version;
    }

    public void setVersion(int version) {
        if (version < 0)
            throw new IllegalArgumentException("Version number is negative");
        this.version = version;
    }

    public boolean hasRealMergedData() {
        return hasRealMergedData;
    }

    public String getReaderName() {
        return readerName;
    }

    public void setReaderName(String readerName) {
        this.readerName = readerName;
    }

    public String getWriterName() {
        return writerName;
    }

    public void setWriterName(String writerName) {
        this.writerName = writerName;
    }

    private void read() {
        int i = 0;
        version = IOUtils.readIntMM(data, i);
        i += 4;
        hasRealMergedData = (data[i++] != 0);
        int writer_size = IOUtils.readIntMM(data, i);
        i += 4;
        writerName = StringUtils.toUTF16BE(data, i, writer_size * 2);
        i += writer_size * 2;
        int reader_size = IOUtils.readIntMM(data, i);
        i += 4;
        readerName = StringUtils.toUTF16BE(data, i, reader_size * 2);
        i += reader_size * 2;
        fileVersion = IOUtils.readIntMM(data, i);
    }

    public void print() {
        super.print();
        LOGGER.info("Version: {}", getVersion());
        LOGGER.info("Has Real Merged Data: {}", hasRealMergedData);
        LOGGER.info("Writer name: {}", writerName);
        LOGGER.info("Reader name: {}", readerName);
        LOGGER.info("File Version: {}", getFileVersion());
    }

    public void setHasRealMergedData(boolean hasRealMergedData) {
        this.hasRealMergedData = hasRealMergedData;
    }

    public void write(OutputStream os) throws IOException {
        if (data == null) {
            ByteArrayOutputStream bout = new ByteArrayOutputStream();
            IOUtils.writeIntMM(bout, version);
            bout.write(hasRealMergedData ? 1 : 0);
            byte[] writerNameBytes = null;
            writerNameBytes = writerName.getBytes(StandardCharsets.UTF_16BE);
            IOUtils.writeIntMM(bout, writerName.length());
            bout.write(writerNameBytes);
            byte[] readerNameBytes = null;
            readerNameBytes = readerName.getBytes(StandardCharsets.UTF_16BE);
            IOUtils.writeIntMM(bout, readerName.length());
            bout.write(readerNameBytes);
            IOUtils.writeIntMM(bout, fileVersion);
            data = bout.toByteArray();
            size = data.length;
        }
        super.write(os);
    }
}
